#ifndef LIBACCENT_FUNCTIONAL_NOT_HPP
#define LIBACCENT_FUNCTIONAL_NOT_HPP

#include <utility>

namespace accent
{
  namespace detail
  {
    template <typename Inner>
    class not_functor
    {
      Inner inner;

    public:
      not_functor(Inner inner) : inner(std::move(inner)) {}

      template <typename... Args>
      auto operator ()(Args&&... args) const
        -> decltype(!inner(std::forward<Args>(args)...))
      {
        return !inner(std::forward<Args>(args)...);
      }
    };
  }

  template <typename Inner>
  detail::not_functor<Inner> not_(Inner inner)
  {
    return { std::move(inner) };
  }
}

#endif
